package com.zhejiangzhengyuan.municipal_common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhejiangzhengyuan.municipal_common.entity.*;
import com.zhejiangzhengyuan.municipal_common.entity.dto.ReceiptCaseDto;
import com.zhejiangzhengyuan.municipal_common.entity.dto.SendCase;
import com.zhejiangzhengyuan.municipal_common.entity.vo.AcceptTestDdetails;
import com.zhejiangzhengyuan.municipal_common.entity.vo.CaseNoHandle;
import com.zhejiangzhengyuan.municipal_common.entity.vo.DeviceVo;
import com.zhejiangzhengyuan.municipal_common.mapper.*;
import com.zhejiangzhengyuan.municipal_common.response.ResponseVo;
import com.zhejiangzhengyuan.municipal_common.service.CaseService;
import com.zhejiangzhengyuan.municipal_common.service.WarnMessageService;
import com.zhejiangzhengyuan.municipal_common.utils.ConstantUtil;
import com.zhejiangzhengyuan.municipal_common.utils.DateFormatUtil;
import com.zhejiangzhengyuan.municipal_common.utils.excelFileUtils.FileUtil;
import com.zhejiangzhengyuan.municipal_common.utils.sms.SendMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;
import java.util.Objects;

import static com.zhejiangzhengyuan.municipal_common.utils.DateFormatUtil.timeFormat;

/**
 * 案件表，案件是对事件来源数据以及相应处理过程和结果的包裹数据 服务实现类
 *
 * @author linju
 * @since 2019-11-22
 */
@Service
@Slf4j
public class CaseServiceImpl extends ServiceImpl<CaseMapper, Case> implements CaseService {
  @Autowired private CaseMapper caseMapper;
  @Autowired private SmsRecordMapper smsRecordMapper;
  @Autowired private WarnEventMapper warnEventMapper;
  @Autowired private WarnEventFileMappingMapper warnEventFileMappingMapper;
  @Autowired private FileMapper fileMapper;
  @Autowired private InspectionEventFileMappingMapper inspectionEventFileMappingMapper;
  @Autowired private DeviceMapper deviceMapper;
  @Autowired private CaseInspectionEventMappingMapper caseInspectionEventMappingMapper;
  @Autowired private CaseReceiptMappingMapper caseReceiptMappingMapper;
  @Autowired private CaseWarnEventMappingMapper caseWarnEventMappingMapper;
  @Autowired private ReceiptMapper receiptMapper;
  @Autowired private ReceiptFileMappingMapper receiptFileMappingMapper;
  @Autowired private WarnMessageService warnMessageService;
  @Autowired private UserInfoMapper userInfoMapper;
  private String manholeDepartmentName = "排水抢修组";

  /** 案件派单和重新派单 */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public ResponseVo saveCase(SendCase sendCase, String caseType, String module) throws IOException {
    Long warnId = sendCase.getWid();
    // 派单需删除之前告警事件之前的消息
    warnMessageService.removeMessageByWarnId(warnId);
    // 若携带caseId 则 重新派单
    Timestamp timestamp = timeFormat(System.currentTimeMillis());
    if (sendCase.getCid() != null && sendCase.getCid() >= 1) {
      Case ca = new Case();
      ca.setId(sendCase.getCid());
      ca.setStatus("案件隐藏");
      ca.setUpdateTime(timestamp);
      caseMapper.updateCaseById(ca);
      // 案件回执关联  若存在则删除回执和回执关联
      QueryWrapper<CaseReceiptMapping> CaseReceiptMappingQueryWrapper = new QueryWrapper<>();
      CaseReceiptMappingQueryWrapper.eq("case_id", sendCase.getCid());
      CaseReceiptMapping caseReceiptMapping =
          caseReceiptMappingMapper.selectOne(CaseReceiptMappingQueryWrapper);
      if (Objects.nonNull(caseReceiptMapping)) {
        caseReceiptMappingMapper.deleteById(caseReceiptMapping.getId());
      }
      // 告警案件关联表存在则删除案件
      QueryWrapper<CaseWarnEventMapping> queryWrapper = new QueryWrapper<>();
      queryWrapper.eq("warn_event_id", warnId);
      CaseWarnEventMapping caseWarnEventMapping =
          caseWarnEventMappingMapper.selectOne(queryWrapper);
      if (Objects.nonNull(caseWarnEventMapping)) {
        caseWarnEventMappingMapper.deleteById(caseWarnEventMapping.getId());
      }
      // 删除告警关联文件 重新派单会携带新的关联文件
      QueryWrapper<WarnEventFileMapping> objectQueryWrapper = new QueryWrapper<>();
      objectQueryWrapper.eq("warn_event_id", warnId);
      List<WarnEventFileMapping> warnEventFileMappings =
          warnEventFileMappingMapper.selectList(objectQueryWrapper);
      if (Objects.nonNull(warnEventFileMappings)) {
        for (WarnEventFileMapping warnEventFileMapping : warnEventFileMappings) {
          File file = fileMapper.selectById(warnEventFileMapping.getFileId());
          FileUtil.removeFile(file.getLink());
          fileMapper.deleteById(file.getId());
          warnEventFileMappingMapper.deleteById(warnEventFileMapping.getId());
        }
      }
    }

    // 把警告事件的状态改为已派单
    Long wid = sendCase.getWid();
    WarnEvent warnEvent = warnEventMapper.selectById(wid);
    warnEvent.setSendOrder(true);
    warnEvent.setUpdateTime(timestamp);
    warnEventMapper.updateById(warnEvent);

    Case C = new Case();
    C.setGrade(sendCase.getGrade());
    C.setCaseDescribe(sendCase.getCaseDescribe());
    C.setAdvice(sendCase.getAdvice());
    // 设置案件包裹的事件类型
    C.setType(caseType);
    // 设置事件的状态
    C.setStatus("新任务");
    // 更新时间
    C.setUpdateTime(timeFormat(System.currentTimeMillis()));
    C.setCreateTime(timeFormat(System.currentTimeMillis()));

    if (caseMapper.insertCase(C) > 0) {
      CaseWarnEventMapping caseWarnEventMapping = new CaseWarnEventMapping();
      caseWarnEventMapping.setCaseId(C.getId());
      caseWarnEventMapping.setWarnEventId(sendCase.getWid());
      caseWarnEventMapping.setCreateTime(timestamp);
      caseWarnEventMapping.setUpdateTime(timestamp);
      caseWarnEventMappingMapper.insert(caseWarnEventMapping);
      // 添加告警消息
      //      insertMessageToDepartment(module, wid, timestamp, manholeDepartmentName);
      insertMessageToDepartment(module, caseType, "领取任务", manholeDepartmentName);
      return ResponseVo.SUCCESS;
    }
    return ResponseVo.SERVER_ERROR;
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public long newCase(Case c, String caseType) {
    c.setType(caseType);
    c.setStatus("新任务");
    c.setCreateTime(timeFormat(System.currentTimeMillis()));
    c.setUpdateTime(timeFormat(System.currentTimeMillis()));
    if (caseMapper.insertCase(c) > 0) {
      return c.getId();
    }
    return 0;
  }

  /** 案件回执 */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public long receiptCase(ReceiptCaseDto receiptCaseDto, String module) {
    QueryWrapper<CaseReceiptMapping> wrapper = new QueryWrapper<>();
    wrapper.eq("case_id", receiptCaseDto.getCid());

    if (caseReceiptMappingMapper.selectOne(wrapper) != null) {
      return 0;
    }
    // 新建回执
    Receipt receipt = new Receipt();
    receipt
        .setMatterReason(receiptCaseDto.getMatterReason())
        .setContext(receiptCaseDto.getContext())
        .setReceiptUserInfoId(Long.valueOf(receiptCaseDto.getReceipt_user_info_id()))
        .setCreateTime(timeFormat(System.currentTimeMillis()))
        .setUpdateTime(timeFormat(System.currentTimeMillis()));
    receiptMapper.insert(receipt);
    // 新建案件回执关联表
    CaseReceiptMapping caseReceiptMapping = new CaseReceiptMapping();
    caseReceiptMapping
        .setCaseId(receiptCaseDto.getCid())
        .setReceiptId(receipt.getId())
        .setCreateTime(timeFormat(System.currentTimeMillis()))
        .setUpdateTime(timeFormat(System.currentTimeMillis()));
    caseReceiptMappingMapper.insert(caseReceiptMapping);
    return receipt.getId();
  }

  // 案件回执打回，需要重新提交回执
  @Override
  @Transactional(rollbackFor = Exception.class)
  public int repeatReceipt(Long cid) {
    // 根据案件ID 查询案件回执表
    QueryWrapper<CaseReceiptMapping> one = new QueryWrapper<CaseReceiptMapping>();
    one.eq("case_id", cid);
    CaseReceiptMapping caseReceiptMapping = caseReceiptMappingMapper.selectOne(one);
    // 根据回执ID 查询文件回执表
    if (caseReceiptMapping != null) {
      QueryWrapper<ReceiptFileMapping> two = new QueryWrapper<>();
      two.eq("receipt_id", caseReceiptMapping.getReceiptId());
      // 删除案件回执表
      caseReceiptMappingMapper.deleteById(caseReceiptMapping.getId());
      List<ReceiptFileMapping> receiptFileMappings = receiptFileMappingMapper.selectList(two);
      for (ReceiptFileMapping receiptFileMapping : receiptFileMappings) {
        receiptFileMappingMapper.deleteById(receiptFileMapping.getId());
      }
    }

    // 删除文件回执表

    return 1;
  }

  // 井盖案件从处理中转向已处理
  @Override
  public int caseHandingTurnToCaseIsHandled(Long cid) {
    QueryWrapper<CaseReceiptMapping> queryWrapper1 = new QueryWrapper<>();
    queryWrapper1.eq("case_id", cid);
    CaseReceiptMapping caseReceiptMapping = caseReceiptMappingMapper.selectOne(queryWrapper1);
    if (caseReceiptMapping == null) {
      return 0;
    }
    Case ca = caseMapper.getById(cid);
    Device device = caseMapper.selectDeviceId(cid);
    if (device.getId() != 1) {
      device.setWarn(false);
      // longitude,latitude
      DeviceVo deviceVo = caseMapper.selectGeromeryId(device.getId());
      if (deviceVo.getLongitude() != null) {
        // 设备的Geo 后续修改
        device.setGeometry(null);
        if (deviceMapper.updateById(device) > 0) {
          // 更新成功后修改geometry
          deviceMapper.updateGeometry(
              device.getId(), deviceVo.getLongitude(), deviceVo.getLatitude());
        }
      }
    }
    QueryWrapper<CaseWarnEventMapping> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("case_id", ca.getId());
    CaseWarnEventMapping caseWarnEventMapping = caseWarnEventMappingMapper.selectOne(queryWrapper);
    warnMessageService.removeMessageByWarnId(caseWarnEventMapping.getWarnEventId());
    return caseMapper.caseHandingTurnToCaseIsHandled(ca);
  }

  // 巡檢案件从处理中转向已处理
  @Override
  public int caseInspectionHandingTurnToCaseIsHandled(Long cid) {
    QueryWrapper<CaseReceiptMapping> queryWrapper1 = new QueryWrapper<>();
    queryWrapper1.eq("case_id", cid);
    CaseReceiptMapping caseReceiptMapping = caseReceiptMappingMapper.selectOne(queryWrapper1);
    if (caseReceiptMapping == null) {
      return 0;
    }
    Case ca = caseMapper.getById(cid);
    QueryWrapper<CaseInspectionEventMapping> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("case_id", ca.getId());
    CaseInspectionEventMapping caseInspectionEventMapping1 =
        caseInspectionEventMappingMapper.selectOne(queryWrapper);
    warnMessageService.removeMessageByWarnId(caseInspectionEventMapping1.getInspectionEventId());
    return caseMapper.caseHandingTurnToCaseIsHandled(ca);
  }

  @Override
  public void insertMessageToDepartment(
      String moduleName, String taskType, String action, String departmentName) {
    List<UserInfo> users = userInfoMapper.getUsersByDepartmentName(departmentName);
    Timestamp timestamp = DateFormatUtil.timeFormat(System.currentTimeMillis());
    for (UserInfo userInfo : users) {
      if (Objects.nonNull(userInfo) && Objects.nonNull(userInfo.getPhoneNum())) {
        String message =
            SendMessage.sendTaskMessage(
                userInfo.getPhoneNum(),
                ConstantUtil.getModuleChineseName(moduleName),
                taskType,
                action);
        // 保存记录
        SmsRecord smsRecord =
            new SmsRecord()
                .setSnedTime(timestamp)
                .setReceivePhone(userInfo.getPhoneNum())
                .setReceiveUserInfoId(userInfo.getId())
                .setIsSuccess(Strings.isBlank(message))
                .setRemark(message);
        smsRecordMapper.insert(smsRecord);
      }
    }
  }

  @Override
  public void insertTomorrowMessageToDepartment(
      String moduleName, String taskType, String action, String startTime, String departmentName) {
    List<UserInfo> users = userInfoMapper.getUsersByDepartmentName(departmentName);
    Timestamp timestamp = DateFormatUtil.timeFormat(System.currentTimeMillis());
    for (UserInfo userInfo : users) {
      if (Objects.nonNull(userInfo) && Objects.nonNull(userInfo.getPhoneNum())) {
        String message =
            SendMessage.sendTomorrowTaskMessage(
                userInfo.getPhoneNum(),
                ConstantUtil.getModuleChineseName(moduleName),
                taskType,
                action,
                startTime);
        // 保存记录
        SmsRecord smsRecord =
            new SmsRecord()
                .setSnedTime(timestamp)
                .setReceivePhone(userInfo.getPhoneNum())
                .setReceiveUserInfoId(userInfo.getId())
                .setIsSuccess(Strings.isBlank(message))
                .setRemark(message);
        smsRecordMapper.insert(smsRecord);
      }
    }
  }

  @Override
  public int changeStatus(Long cid) {
    Case ca = new Case();
    ca.setId(cid);
    int i = caseMapper.changeStatus(ca);
    return i;
  }

  @Override
  public AcceptTestDdetails mobileAcceptTestDdetails(Long cid) {
    AcceptTestDdetails acceptTestDdetails = caseMapper.acceptTestDdetails(cid);
    String link = fileMapper.selectInspectionFile(acceptTestDdetails.getIid()).getLink();
    acceptTestDdetails.setLink(link);
    return acceptTestDdetails;
  }

  // 派单新建多文件上传，每次单次上传
  @Override
  public int uploadToFile(long cid, MultipartFile file1, String moduleName) throws IOException {
    if (file1 != null) {
      File file = FileUtil.getFilePo(null, moduleName, file1);
      newFile(cid, file, fileMapper, warnEventFileMappingMapper);
    }
    return 1;
  }

  // 回执多文件上传
  @Override
  public int uploadReceiptToFile(long rid, MultipartFile file, String moduleName)
      throws IOException {
    if (file != null) {
      File file1 = FileUtil.getFilePo(null, moduleName, file);
      fileMapper.insert(file1);
      // 新建回执文件关联表
      ReceiptFileMapping receiptFileMapping = new ReceiptFileMapping();
      receiptFileMapping
          .setFileId(file1.getId())
          .setReceiptId(rid)
          .setCreateTime(timeFormat(System.currentTimeMillis()))
          .setUpdateTime(timeFormat(System.currentTimeMillis()));
      receiptFileMappingMapper.insert(receiptFileMapping);
      return 1;
    }
    return 0;
  }

  // 派单，新建，重新派单文件上传
  @Override
  public int uploadInspectionToFile(long iid, MultipartFile file, String moduleName)
      throws IOException {
    if (file != null) {
      File file1 = FileUtil.getFilePo(null, moduleName, file);
      fileMapper.insert(file1);
      InspectionEventFileMapping inspectionEventFileMapping = new InspectionEventFileMapping();
      inspectionEventFileMapping
          .setFileId(file1.getId())
          .setInspectionEventId(iid)
          .setCreateTime(timeFormat(System.currentTimeMillis()))
          .setUpdateTime(timeFormat(System.currentTimeMillis()));
      inspectionEventFileMappingMapper.insert(inspectionEventFileMapping);
      return 1;
    }
    return 0;
  }

  @Override
  public CaseNoHandle mobileOtherTestDdetails(Long cid) {
    return caseMapper.mobileOtherTestDdetails(cid);
  }

  static void newFile(
      long cid,
      File file,
      FileMapper fileMapper,
      WarnEventFileMappingMapper warnEventFileMappingMapper) {
    if (fileMapper.insert(file) > 0) {
      Long fileId = file.getId();
      WarnEventFileMapping warnEventFileMapping = new WarnEventFileMapping();
      warnEventFileMapping.setFileId(fileId);
      warnEventFileMapping.setWarnEventId(cid);
      warnEventFileMapping.setCreateTime(timeFormat(System.currentTimeMillis()));
      warnEventFileMapping.setUpdateTime(timeFormat(System.currentTimeMillis()));
      warnEventFileMappingMapper.insert(warnEventFileMapping);
    }
  }
}
